#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctime>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <unordered_map>

#include "DeoLexicon.h"
 
using namespace std;

/* lexicon file */
fstream lex_file;   


DeoLexicon* _makeLexicon(string dictFile) {
	DeoLexicon *lexicon = new DeoLexicon();
	lex_file.open(dictFile, std::ios_base::in);
	vector<string> allWords;
	string s1;
	while (lex_file.good()) {
		getline(lex_file, s1,'\n');
		if (s1.empty())
			continue;
		allWords.push_back(s1);
	}
	lexicon->make_automat(allWords.begin(), allWords.end());
	lex_file.close();
	//lex_file.open(dictFile, std::ios_base::in);
	//if (!lexicon.check_string(subString)) {
	//			cout << "Not found " << subString << endl;
	//			cout << "Suggestions:\n";
	//			list<string> suggestions = getSuggestionList(subString, lexicon);
	//			for (auto it = suggestions.begin(); it != suggestions.end(); it++)
	//				cout << (*it) << endl;
	//		}
	//lexicon.make_automat(allWords.begin(), allWords.end());
	return lexicon;
}

vector<string> _getWordsFromText(string testFile) {
	vector<string> textWords;
	fstream inputFile;
	string s, subString;
	inputFile.open(testFile.c_str());
	string strToRemove = ".,();:[]{}-_\\/";
	cout << "File to test is opened\n";
	while (inputFile.good()) {
		getline(inputFile, s, '\n');
		if (s.empty())
			continue;
		for (auto it = strToRemove.begin(); it!=strToRemove.end(); it++)
			s.erase(std::remove(s.begin(), s.end(), *it), s.end());
		istringstream iss(s);
		while (iss) {
			iss >> subString;
			transform(subString.begin(), subString.end(), 
				subString.begin(), ::tolower);
			textWords.push_back(subString);
		}
	}
	return textWords;
}

string _nameForCurrentDateTime() {
	const time_t saveTimeDate = time(0);
	struct tm * now = localtime( & saveTimeDate );
	//localtime_s(now, &saveTimeDate);
	stringstream ss;
	//ss << "f:\\automat";
	ss << now->tm_year+1900 << "-" << now->tm_mon+1 << "-" << now->tm_mday << " ";
	ss << now->tm_hour << "h" << now->tm_min << "m" << now->tm_sec << "s";
	ss << ".au";
	return ss.str();
}

void testCheckAutomaton(const char *dictFile, const char *automaFile) {
	DeoLexicon lexicon;
	lex_file.open(dictFile, std::ios_base::in);
    lexicon.read_automat(automaFile);
	vector<string> allWords;
	string s1;
	while (lex_file.good()) {
		getline(lex_file, s1,'\n');
		if (s1.empty())
			continue;
		allWords.push_back(s1);
	}
	bool result = lexicon.test_automat(allWords.begin(), allWords.end());
	lex_file.close();
	if (result) printf("test function finished succesfully\n");
	else printf("test function failed!!!!!!!!\n");
}

void makeNewAutomaton(const char *dictFile, const char *automaFile) {
	printf("---make function started---\n");
	DeoLexicon lexicon;
	lex_file.open(dictFile, std::ios_base::in);
    vector<string> allWords;
	string s1;
	while (lex_file.good()) {
		getline(lex_file, s1,'\n');
		if (s1.empty())
			continue;
		allWords.push_back(s1);
	}
	cout << "Automat created.\n";
	lex_file.close();
	lexicon.save_automat(automaFile);
	printf("Automat saved.\n");
	printf("---make function finished---\n");
}

void listStrings(string dictFile, const char *dictOutFile) {
	//unsigned char tempStr[255];
	printf("---listStrings function started---\n");
	DeoLexicon *lexicon = _makeLexicon(dictFile);
	cout << "Automat created.\n";
	printf("automat opened and loaded to memory\n");
	lexicon->currentState.pos = lexicon->start_state;
	lex_file.open(dictOutFile, std::ios_base::out);
	DeoLexicon::myIterator iter(*lexicon);
	for (DeoLexicon::myIterator iter(*lexicon); iter != iter.end(); iter++) {
		cout << *iter++ << endl;
	}
	//lexicon.list_strings(lexicon.start_state, 0, tempStr);
	printf("lexicon created\n");
	lex_file.close();
	delete lexicon;
	printf("---listStrings function finished---\n");
}

list<string> getSuggestionList(string &word, DeoLexicon& lexicon) {
	list<string> suggestionList;
	unsigned i,j;
	unsigned char c;
	// Remove 1 character.
	if (word.length()>1) {
		for (i=0; i<word.length(); i++) {
			string s = word;
			s.erase(s.begin()+i);
			if (lexicon.check_string(s))
				suggestionList.push_back(s);
		}
	}

	// Add 1 character.
	for (i=0; i<word.length(); i++) {
		for (c = 'a'; c<='z';c++) {
			string s = word;
			s.insert(i,1,c);
			if (lexicon.check_string(s))
				suggestionList.push_back(s);
		}
	}

	// Swap characters.
	for (i=0; i<word.length()-1; i++) {
		for (j=i+1; j<word.length(); j++) {
			string s = word;
			std::swap(s[i], s[j]);
			if (lexicon.check_string(s))
				suggestionList.push_back(s);
		}
	}

	// Change 1 character.
	for (i=0; i<word.length(); i++) {
		for (c='a'; c<='z';c++){
			string s = word;
			s[i] = c;
			if (lexicon.check_string(s))
				suggestionList.push_back(s);
		}
	}

	return suggestionList;
}

void statCheckText(string textToVerify, string dictionaryFile) {
	DeoLexicon *lex = _makeLexicon(dictionaryFile);
	vector<string> textWords = _getWordsFromText(textToVerify);

}

int main(int argc, char **argv)
{
	string automaName = _nameForCurrentDateTime();
	string dictionary = string("polish.dic");//string("english_s.dic");
	string textOutput = string("outPut.txt");
	string textToVerify = string("pan_tadeusz_ks1.txt");
	
	//makeNewAutomaton(dictionary.c_str(), automa_name.c_str());
	//testCheckAutomaton(dictionary.c_str(), automa_name.c_str());
	//listStrings(dictionary.c_str(), text2.c_str());
	statCheckText(dictionary, textToVerify);
    fgetc(stdin);
    return EXIT_SUCCESS;
}